package com.aipsi.cws.supplier.util;


import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotEmpty;
import javax.validation.executable.ExecutableValidator;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Set;

/**
 * @author 大忽悠
 * @create 2022/4/13 20:07
 */
public class ValidatorUtils {
   private static final String EMPTY_STR="\"\"";
    /**
     * @return 于Java Bean校验的校验器
     */
    private static Validator obtainValidator() {
        // 1、使用【默认配置】得到一个校验工厂  这个配置可以来自于provider、SPI提供
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        // 2、得到一个校验器
        return validatorFactory.getValidator();
    }


    /**
     * @return 返回用于方法校验的校验器
     */
    private static ExecutableValidator obtainExecutableValidator() {
        return obtainValidator().forExecutables();
    }

    /**
     * 对方法和方法上的参数进行数据校验
     */
    public  static void doValid(Object thisObj, Method method, Object[] args) {
        Set<ConstraintViolation<Object>> validResult = obtainExecutableValidator().validateParameters(thisObj, method, args);
        //错误结果的字符串
        StringBuilder resStr=new StringBuilder();
        //对NotEmpty注解做特殊处理
        specialHandleWithNotEmpty(method,args,resStr);
        if (!validResult.isEmpty()||!resStr.toString().isEmpty()) {
            // ... 输出错误详情validResult
            validResult.stream().map(v -> v.getPropertyPath() + " " + v.getMessage() + ",传入的非法值为:" + v.getInvalidValue()+"\n").forEach(v->resStr.append(v));
            throw new IllegalArgumentException(resStr.toString());
        }
    }

    private static void specialHandleWithNotEmpty(Method method, Object[] args,StringBuilder stringBuilder) {
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter=parameters[i];
            if(parameter.isAnnotationPresent(NotEmpty.class))
            {
                NotEmpty notEmpty = parameter.getAnnotation(NotEmpty.class);
                String param = (String) args[i];
                if(param.equals(EMPTY_STR))
                {
                    stringBuilder.append(method.getName()+"."+parameter.getName()+" "+notEmpty.message()+"\n");
                }
            }
        }
    }

}
